#include "modbuspoller.h"

ModbusPoller::ModbusPoller(QObject *parent)
    : QObject{parent}
{
    connected=false;
    // 配置定时器
    pollTimer.setInterval(100);  // 200ms轮询周期
    connect(&pollTimer, &QTimer::timeout, this, &ModbusPoller::pollData);

    // 初始化Modbus主站
    modbusMaster = new QModbusRtuSerialMaster(this);

    // connect_device();//连接设备
    // startPolling();//开始访问寄存器

}



//开始轮询数据
void ModbusPoller::startPolling()
{



    if(connected) {
        pollTimer.start();
        qDebug() << "开始轮询数据...";
    }
    else
    {
        qDebug() << "轮询数据失败,设备未连接!";
    }
}

void ModbusPoller::stopPolling()
{
    //停止计时器
    pollTimer.stop();
}

void ModbusPoller::disconnect_device()
{
    modbusMaster->disconnectDevice();
    qDebug()<<"设备已经成功断开连接";
}

//尝试连接设备
bool ModbusPoller::connect_device()
{
    if(connected==false)
    {
        //尝试连接设备
        if(modbusMaster->connectDevice()) {
            // pollTimer.start();
            // qDebug() << "开始轮询数据...";
            qDebug() << "设备连接成功";
            // get_active_devices();
            connected=true;


            return true;
        }
        else
        {
            qDebug()<<"设备连接失败";
            connected=false;
            return false;
        }
    }
}



void ModbusPoller::pollData() {
    static int retryCount = 0;

    //从寄存器0读到寄存器39
    QModbusDataUnit readUnit(QModbusDataUnit::HoldingRegisters, 0, 39);
    // 发送读取请求（从站地址1，保持寄存器）
    if(auto *reply = modbusMaster->sendReadRequest(readUnit, 1)) {
        connect(reply, &QModbusReply::finished, this, [=](){
            if(reply->error() == QModbusDevice::NoError) {
                retryCount = 0;  // 重置重试计数器
                processModbusResponse(reply->result());
            } else {
                if(++retryCount > 3) {
                    qCritical() << "连续错误超过3次，停止轮询";
                    pollTimer.stop();
                }
                qDebug() << "读取错误：" << reply->errorString();
            }
            reply->deleteLater();
        });
    }
}

void ModbusPoller::processModbusResponse(const QModbusDataUnit &unit) {
    // 补码转换处理
    QVector<qint16> convertedData;
    for(const auto &value : unit.values()) {
        qDebug().nospace()<<value;
        convertedData.append((value & 0x8000) ?
                                 static_cast<qint16>(value - 0x10000) :
                                 static_cast<qint16>(value));
    }

    if(receive_processor_list==nullptr){qDebug()<<"接收配置文件列表指针为空";return;}

    for(int device_index=0;device_index<receive_processor_list->count();device_index++)
    {
        //清空真实数值
        receive_processor_list->value(device_index)->real_value_list->clear();
        for(int param_index=0;param_index<receive_processor_list->value(device_index)->register_location->count();param_index++)
        {
            //采用倒数第一位的寄存器的数值作为该参数的数值
            //经补码转换后,负数会直接转为负
            int last_index=receive_processor_list->value(device_index)->register_location->value(param_index)->count()-1;
            qDebug()<<(receive_processor_list->value(device_index)->register_location->value(param_index)->count()-1);
            qint16 real_value_temp=convertedData.value(receive_processor_list->value(device_index)->
            register_location->value(param_index)->value(last_index));
            double real_value=real_value_temp*receive_processor_list->value(device_index)->coefficient_list->value(param_index);
            qDebug()<<"参数"<<param_index<<"乘以系数后的数值:"<<real_value;
            receive_processor_list->value(device_index)->real_value_list->push_back(real_value);
        }
        if(history_page==nullptr){qDebug()<<"历史查询页面指针为空";continue;}
        if(device_monitor==nullptr){qDebug()<<"数据监控页面指针为空";continue;}
        this->device_monitor->updateData(receive_processor_list,device_index);//更新数据详细显示页面的数据
        this->history_page->insert_Data(receive_processor_list,device_index);//添加数据到历史查询面板
    }
}

void ModbusPoller::SetUpModbusRTU(
    const QVariant &Port,
    const QVariant &BaudRate,
    const QVariant &Parity,
    const QVariant &DataBits,
    const QVariant &StopBits,
    int Time_out
    ) {
    // 配置串口参数（根据设备调整）
    modbusMaster->setConnectionParameter(QModbusDevice::SerialPortNameParameter, Port);
    modbusMaster->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, BaudRate);
    modbusMaster->setConnectionParameter(QModbusDevice::SerialParityParameter, Parity);
    modbusMaster->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, DataBits);
    modbusMaster->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, StopBits);
    modbusMaster->setTimeout(Time_out);
}

